/********************************
功  能：定时/计数器实现门铃打铃的声音
编程人：ZZT
版  本：V1.0
时  间：2023/12/23
**********************************/
//头文件声明
#include <Reg51.h>
#include "Key.h"

//IO的声明
sbit DoorBell = P2^5;//蜂鸣器

//全局变量的声明
unsigned int  timerCnt;//计数变量 声音持续50ms
unsigned char uc500Hz = 0;//计数变量 咚 500Hz
unsigned char uc700Hz = 0;//计数变量 叮 700Hz
unsigned char flag = 0;//标志变量

//函数的声明
void Timer0Init(void);//定时器0初始化
void keyService();//按键服务函数，打开和关闭定时器

/**********************************
函数名：main
功  能：完成程序模块的调用
参  数：无
返回值：无
***********************************/
void main()
{
	Timer0Init();
	while(1)
	{
		keyService();
	}
}

/**********************************
函数名：keyService
功  能：按下按键，打开和关闭定时器0
参  数：无
返回值：无
***********************************/
void keyService()
{
	switch(Key_Scan())
	{
		case 1:break;
		case 2:break;
		case 3:TR0 = ~TR0;break;//按下按键3，打开和关闭定时器0
		case 4:break;
		default:break;
	}
}
void Timer0Init(void)		//250微秒@11.0592MHz
{
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0x1A;		//设置定时初值
	TH0 = 0xFF;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	ET0 = 1;
	EA = 1;
	//TR0 = 1;		//定时器0开始计时
}

/************************************
1、中断服务函数一定是一个没有返回值的函数
2、中断服务函数一定是没有参数的函数
3、中断服务函数函数名后跟关键字 interrupt
4、interrupt n 0 - 4  5个中断源     8 * n + 0003H 
   0003H INT0 00BH T0 0013H INT1 001BH T1 0023H ES
5、中断服务函数不能被主程序或其他程序所调用
6、n 后面 跟 using m (0 - 3) 工作寄存器组
***************************************/
void Timer0_ISR(void) interrupt 1
{
	timerCnt++;
	if (timerCnt >= 2000)//定时5ms
	{
		timerCnt = 0;
		flag = ~flag;
	}
	if (!flag)//实现叮的发声
	{
		uc700Hz++;
		if (uc700Hz >= 3)
		{
			uc700Hz = 0;
			DoorBell = ~DoorBell;
		}
	}
	if (flag)//实现咚的发声
	{
		uc500Hz++;
		if (uc500Hz >= 4)
		{
			uc500Hz = 0;
			DoorBell = ~DoorBell;
		}
	}
	TL0 = 0x1A;		//设置定时初值
	TH0 = 0xFF;		//设置定时初值
}
